package linklist

import (
	"fmt"
	"sync"
)

//双向链表实现

//双向链表节点,用于存放数据
type DoubleNode struct {
	//前一个节点
	Prev *DoubleNode
	//后一个节点
	Next *DoubleNode

	Data interface{}
}

//双向链表
type DoubleNodeList struct {

	//读写锁
	mutex *sync.RWMutex

	//头节点
	head *DoubleNode
	//尾节点
	tail *DoubleNode

	//链表长度
	size uint
}

//获取双向链表
func NewDoubleNodeList() *DoubleNodeList {

	return &DoubleNodeList{
		mutex: new(sync.RWMutex),
	}

}

//弹出头部节点
func (this *DoubleNodeList) PopHead() {

	//加锁
	this.mutex.Lock()
	defer this.mutex.Unlock()

	switch this.size {
	case 0:
		return
	case 1:
		this.head = nil
		this.tail = nil
	default:
		this.head.Next.Prev = nil
		this.head = this.head.Next
	}

	this.size--

}

//弹出尾部节点
func (this *DoubleNodeList) PopTail() {

	//加锁
	this.mutex.Lock()
	defer this.mutex.Unlock()

	switch this.size {
	case 0:
		return
	case 1:
		this.head = nil
		this.tail = nil
	default:
		this.tail.Prev.Next = nil
		this.tail = this.tail.Prev
	}

	this.size--

}

//通过索引获取节点
func (this *DoubleNodeList) GetNode(index uint) (node *DoubleNode) {

	if index >= this.size {
		return
	}

	node = this.head

	i := uint(0)
	for {
		if i == index {
			break
		}

		if node.Next != nil {
			node = node.Next
		}

		i++
	}

	return
}

//往头部增加节点
func (this *DoubleNodeList) Before(node *DoubleNode) {
	if node == nil {
		return
	}

	//加锁
	this.mutex.Lock()
	defer this.mutex.Unlock()

	switch this.size {
	case 0:
		this.head = node
		this.tail = node
	default:

		this.head.Prev = node
		node.Next = this.head

		this.head = node
	}

	this.size++
}

//往尾部增加节点
func (this *DoubleNodeList) Append(node *DoubleNode) {
	//加锁
	this.mutex.Lock()
	defer this.mutex.Unlock()

	switch this.size {
	case 0:
		this.head = node
		this.tail = node
	default:
		node.Prev = this.tail
		this.tail.Next = node

		this.tail = node
	}

	this.size++
}

//删除任意节点
func (this *DoubleNodeList) Del(index uint) {
	//加锁
	this.mutex.Lock()
	defer this.mutex.Unlock()

	var (
		currentNode *DoubleNode
	)

	if currentNode = this.GetNode(index); currentNode == nil {
		return
	}

	if currentNode.Prev != nil {
		currentNode.Prev.Next = currentNode.Next
	} else {
		//当前节点为第一个节点
		this.head = nil
	}

	this.size--
}

//增加任意节点
func (this *DoubleNodeList) Insert(index uint, node *DoubleNode) {
	var (
		currentNode *DoubleNode
	)

	//加锁
	this.mutex.Lock()
	defer this.mutex.Unlock()

	if node == nil {
		return
	}

	if currentNode = this.GetNode(index); currentNode == nil {
		//越界则往最后加入节点
		node.Prev = this.tail
		this.tail.Next = node
		this.tail = node
		this.size++

		return
	}
	node.Prev = currentNode

	if currentNode.Prev != nil {
		currentNode.Prev.Next = node
		node.Next = currentNode

	} else {
		//当前节点为第一个节点
		node.Next = currentNode
		this.head = node

	}

	this.size++
}

//打印节点信息
func (this *DoubleNodeList) Print() {
	var (
		currentNode *DoubleNode
	)
	currentNode = this.head
	if currentNode == nil {
		return
	}

	fmt.Println("链表长度:", this.size)

	for {
		//fmt.Printf("%p,pre:%p,next:%p,key:%s,value:%s\n",currentNode,currentNode.Prev,currentNode.Next,currentNode.Key,currentNode.Value)

		fmt.Println(currentNode.Data)

		if currentNode.Next == nil {
			break
		}

		currentNode = currentNode.Next

	}

}
